package app.displayTree
{
    import app.configuration.NodeFileMeta;
    import app.debug.APPLog;
    import app.displayTree.analyze.DisplayTreeAnalyst;
    import app.displayTree.fixer.shape.DisplayTreeShapeFixer;
    import app.displayTree.fixer.text.DisplayTreeTextFieldFixer;
    import app.displayTree.optimizer.DisplayTreeOptimizer;
    import app.displayTree.special.SpecialSymbolManger;
    import app.utils.AppFileUtils;

    import copyengine.infoTree.meta.CESFileMeta;

    import flash.display.DisplayObject;
    import flash.system.ApplicationDomain;
    import flash.utils.Dictionary;

    public final class DisplayTreeBuildManger
    {
        private var displayTreeAnalyst:DisplayTreeAnalyst;
        private var shapeFixer:DisplayTreeShapeFixer;

        private var mDisplayTreeOptimizer:DisplayTreeOptimizer;

        private var mSpecialSymbolManger:SpecialSymbolManger; //特殊符号处理
        private var mAllNormalSymbolDic:Dictionary; //存储所有的Normal类型的Mc

        public function DisplayTreeBuildManger() {
        }

        public function prepare(_domain:ApplicationDomain):void {
            displayTreeAnalyst = new DisplayTreeAnalyst();
            mDisplayTreeOptimizer = new DisplayTreeOptimizer();
            shapeFixer = new DisplayTreeShapeFixer();
            mAllNormalSymbolDic = new Dictionary();
            mSpecialSymbolManger = new SpecialSymbolManger();

            mSpecialSymbolManger.initialize();
            displayTreeAnalyst.setSpecialSymbolManger(mSpecialSymbolManger);

            var allOutputKeys:Vector.<String> = _domain.getQualifiedDefinitionNames();
            for each (var key:String in allOutputKeys) {
                var MC_CLASS:Class = _domain.getDefinition(key) as Class;
                var mc:DisplayObject = new MC_CLASS();

                //先遍历一遍所有特殊的Mc,将这些特殊的Mc解析好
                //以后再遇到这些特殊的Mc则直接使用特殊的解析流程
                if (!mSpecialSymbolManger.tryToPushSpecialSymbol(key, mc)) {
                    mAllNormalSymbolDic[key] = mc;
                }
            }
        }

        public function startAnalyzeFile(_configNodeFile:NodeFileMeta):void {
            if (_configNodeFile.isShareTexture) {
                doAnalyzeFileWithShareTexture(mAllNormalSymbolDic, _configNodeFile);
            }
            else {
                doAnalyzeFileWithoutShareTexture(mAllNormalSymbolDic, _configNodeFile);
            }
        }

        /**
         * ShareTexture的方式 是指FLA中所有的导出元件共享纹理图,
         * 即一个FLA的所有png共享一个output文件夹
         */
        private function doAnalyzeFileWithShareTexture(_allNormalSymbolMcDic:Dictionary, _configNodeFile:NodeFileMeta):void {
            //=======分析每个Mc
            //每一个swf文件对一个FileMeta作为Root
            var fileMeta:CESFileMeta = new CESFileMeta();
            fileMeta.allSubSymbolDic = {};
            fileMeta.isShareTexture = true;
            fileMeta.fileName = _configNodeFile.fileName;

            for (var normalMcKey:String in _allNormalSymbolMcDic) {
                APPLog.log("start analyze mc : " + normalMcKey);
                var mc:DisplayObject = _allNormalSymbolMcDic[normalMcKey];
                SWFInfoTree.gameStage.addChild(mc);
                fileMeta.allSubSymbolDic[normalMcKey] = displayTreeAnalyst.analyze(mc);
                SWFInfoTree.gameStage.removeChild(mc);
                APPLog.log("finish analyze mc : " + normalMcKey);
            }

            APPLog.log("start packing file : " + fileMeta.fileName);
            //=======导出PNG和XML文件
            packerAndExportPNGAndXMLFile(fileMeta, _configNodeFile.textureFileOutputPath + "/" + _configNodeFile.fileName);
            APPLog.log("finish packing file : " + fileMeta.fileName);
            //=======序列化并导出File文件
            exportCEFile(fileMeta, _configNodeFile);
        }

        /**
         * 不是ShareTexture的方式输出 将FLA中的每一个导出类均看做一个独立的元件 之间的纹理图不会共享
         * 比如A导出类中使用的closeBtn B导出类中也使用了closeBtn 则会导出两张closeBtn的图
         * 这样做对于大型项目来说 方便做 某一个模块的独立加载与卸载(因为纹理独立 A模块退出时候可以直接Remove 所有纹理)
         */
        private function doAnalyzeFileWithoutShareTexture(_allSymbolMcDic:Dictionary, _configNodeFile:NodeFileMeta):void {
            //=======分析每个Mc
            var fileMeta:CESFileMeta = new CESFileMeta();
            fileMeta.allSubSymbolDic = {};
            fileMeta.isShareTexture = false;
            fileMeta.fileName = _configNodeFile.fileName;

            for (var normalMcKey:String in _allSymbolMcDic) {
                APPLog.log("start analyze mc : " + normalMcKey);
                fileMeta.allSubSymbolDic[normalMcKey] = displayTreeAnalyst.analyze(_allSymbolMcDic[normalMcKey]);
                APPLog.log("finish analyze mc : " + normalMcKey);

                //=======导出PNG和XML文件
                APPLog.log("start packing mc : " + normalMcKey);
                packerAndExportPNGAndXMLFile(fileMeta, _configNodeFile.textureFileOutputPath + "/" + _configNodeFile.fileName + "/" + _configNodeFile.fileName + "_" + normalMcKey);
                APPLog.log("finish packing mc : " + normalMcKey);

                //清空当前Push进去的纹理信息
                displayTreeAnalyst.clean();
            }
            //=======序列化并导出File文件
            exportCEFile(fileMeta, _configNodeFile);
        }

        private function packerAndExportPNGAndXMLFile(_fileMeta:CESFileMeta, _pngFileOutputPath:String):void {
            //=====修正所有Shape信息
            shapeFixer.fixShapeMetaProperty(displayTreeAnalyst.getAllShapeMetaWarpVector());

            //=====修正所有TextField信息
            DisplayTreeTextFieldFixer.fixTextFieldMetaProperty(displayTreeAnalyst.getAllTextFieldMetaWrapVector());

            //========优化显示树节点
            mDisplayTreeOptimizer.optimize(_fileMeta);

            var eachImgDic:Dictionary = displayTreeAnalyst.getAllExportTextureBitmapDic();
            for (var eachImgName:String in eachImgDic) {
                AppFileUtils.writeImgToPath(eachImgDic[eachImgName], _pngFileOutputPath + "/" + eachImgName + ".png");
                APPLog.log("Write Img : " + eachImgName);
            }
        }

        private function exportCEFile(_fileMeta:CESFileMeta, _configNodeFile:NodeFileMeta):void {
            //=======序列化并导出File文件
            AppFileUtils.exportFileMeta(_fileMeta, _configNodeFile.metaFileOutputPath, _configNodeFile.fileName);
        }


    }
}
